/*
 * p2411.cpp
 *
 *  Created on: 2013-8-1
 *      Author: zy状态压缩:F[i][j]:前i行，第i行状态为j的方案数。
状态的含义：1表示这个点是竖着放的第二行，或横着放的，0表示这个点是竖着放的第一行。
样例：11011110011
          00101101100
          …
         11111111111
F[i][j]=Sum(F[i-1][k] )（j与k不冲突）
ans=F[n][111...1]
检测冲突：同一行内：检测1是否配对
                 两行：i-1为0，则i为1，否则检测1的配对
 */
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 12;
long long f[maxn][2050];
int h, w, cnt;
bool one(int i)
{
	for (int k = 0; k < w;)
	{
		if (i & (1 << k))
		{
			if (k == w - 1 || !(i & (1 << (k + 1))))
				return false;
			k += 2;
		}
		else
			k++;
	}
	return true;
}
bool two(int i, int j)
{
	for (int k = 0; k < w;)
	{
		int t = 1 << k;
		int p = 1 << (k + 1);
		if ((j & t) == 0)
		{
			if ((i & t) == 0)
				return false;
			k++;
		}
		else
		{
			if ((i & t))
			{
				if (k == w - 1 || (i & p) == 0 || (j & p) == 0)
					return false;
				k += 2;
			}
			else
				k++;
		}
	}
	return true;
}
int main()
{
	while (scanf("%d%d", &h, &w) && h && w)
	{
		if (h < w)
		{
			int t = w;
			w = h;
			h = t;
		}
		cnt = (1 << w) - 1;
		memset(f, 0, sizeof(f));
		for (int i = 0; i <= cnt; i++)
			if (one(i))
				f[1][i] = 1;
		for (int i = 2; i <= h; i++)
			for (int j = 0; j <= cnt; j++)//Rowi
				for (int k = 0; k <= cnt; k++)//Row i-1
					if (two(j, k))
						f[i][j] += f[i - 1][k];
		cout << f[h][cnt] << endl;
	}
	return 0;
}
